package com.light.gamecomponents;

import java.util.ArrayList;

import javax.microedition.khronos.opengles.GL10;

import org.anddev.andengine.engine.camera.Camera;
import org.anddev.andengine.engine.handler.IUpdateHandler;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.sprite.Sprite;
import org.anddev.andengine.extension.physics.box2d.PhysicsWorld;
import org.anddev.andengine.input.touch.TouchEvent;
import org.anddev.andengine.opengl.texture.region.TextureRegion;
import org.anddev.andengine.ui.activity.BaseGameActivity;

import android.content.res.Configuration;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;

import com.badlogic.gdx.math.Vector2;
import com.light.buttons.Button.ButtonState;
import com.light.gamecomponents.physics.RollerPhysicsWorld;
import com.light.roller.Direction;
import com.light.roller.ResourceManager;
import com.light.roller.Roller;

public class GameForm implements IGameComponents, IUpdateHandler, SensorEventListener{

	protected ArrayList<FormButton> buttonList = new ArrayList<FormButton>();
	protected ArrayList<FormRunningText> runningTextList = new ArrayList<FormRunningText>();
	protected ArrayList<Vector2> runningTextPositionList = new ArrayList<Vector2>();
	protected ArrayList<Vector2> buttonPositionList = new ArrayList<Vector2>();
	protected Sprite m_sprite;
	protected TextureRegion m_textureRegion;
	protected BaseGameActivity m_game;
	protected Vector2 m_position;
	protected Direction m_direction;

	
	public GameForm(BaseGameActivity game, Vector2 position)
	{
		m_game = game;
		m_position = position;
	}
	
	public void addButton(FormButton button, Vector2 position)
	{
		buttonList.add(button);
		buttonPositionList.add(position);
	}
	
	public void addRunningText(FormRunningText runningText, Vector2 position)
	{
		runningTextList.add(runningText);
		runningTextPositionList.add(position);
	}
	
	@Override
	public void onLoadEngine() {
		
	}

	@Override
	public void onLoadResources() {
		for (int i = 0; i < runningTextList.size(); i++)
			runningTextList.get(i).onLoadResources();
		for (int i = 0; i < buttonList.size(); i++)
			buttonList.get(i).onLoadResources();
		
		ResourceManager.onLoadResources("FormPanel", m_game);
		this.m_textureRegion = ResourceManager.getTextureRegion("FormPanel");
	}

	@Override
	public void unLoadResources() {
		for (int i = 0; i < buttonList.size(); i++)
			buttonList.get(i).unLoadResources();
		for (int i = 0; i < runningTextList.size(); i++)
			runningTextList.get(i).unLoadResources();
	}

	@Override
	public void onLoadScene(Scene scene, PhysicsWorld physicsWorld) {

		int centerX = (int)(m_position.x - this.m_textureRegion.getWidth() / 2);
        int centerY =  (int)(m_position.y - this.m_textureRegion.getHeight() / 2);
        m_position.x = centerX;
        m_position.y = centerY;
		m_sprite = new Sprite(centerX, centerY, this.m_textureRegion)
		{
			@Override
        	public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float pTouchAreaLocalX, float pTouchAreaLocalY)
        	{
				if (pSceneTouchEvent.isActionUp())
				{
					if (!runningTextList.isEmpty())
						actionButtonCall();
				}
				return false;
        	}
		};
		m_sprite.setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
		scene.attachChild(m_sprite);
		scene.registerTouchArea(m_sprite);
		((RollerPhysicsWorld)physicsWorld).registerUpdateHandler(this);
		
	    for (int i = 0; i < buttonList.size(); i++)
		{
			buttonList.get(i).onLoadScene(scene, physicsWorld);
			Vector2 temp = new Vector2(buttonPositionList.get(i).x + m_sprite.getX(),
					                   buttonPositionList.get(i).y + m_sprite.getY());
			buttonList.get(i).setPosition(temp);
			temp = new Vector2(m_sprite.getWidth() / 2 - buttonPositionList.get(i).x,
						       m_sprite.getHeight() / 2 - buttonPositionList.get(i).y);
			buttonList.get(i).setRotationCenter(temp);
		}
	    
	    for (int i = 0; i < runningTextList.size(); i++)
		{
	    	runningTextList.get(i).onLoadScene(scene, physicsWorld);
			Vector2 temp = new Vector2(runningTextPositionList.get(i).x + m_sprite.getX(),
									   runningTextPositionList.get(i).y + m_sprite.getY());
			runningTextList.get(i).setPosition(temp);
			temp = new Vector2(m_sprite.getWidth() / 2 - runningTextPositionList.get(i).x,
						       m_sprite.getHeight() / 2 - runningTextPositionList.get(i).y);
			runningTextList.get(i).setRotationCenter(temp);
		}
		
	    
		hideForm();
		
	}

	@Override
	public void removeFromScene(Scene scene, PhysicsWorld physicsWorld) 
	{
		scene.detachChild(m_sprite);
		m_sprite = null;
		
		for (int i = 0; i < buttonList.size(); i++)
			buttonList.get(i).removeFromScene(scene, physicsWorld);
		for (int i = 0; i < buttonList.size(); i++)
			runningTextList.get(i).removeFromScene(scene, physicsWorld);
	}
	
	public void showForm()
	{
		m_sprite.setAlpha(1.0f);
		Camera tempCamera = Roller.cameraManager.getCamera();
		setByCameraPosition(tempCamera.getCenterX(), tempCamera.getCenterY());
	    for (int i = 0; i < buttonList.size(); i++)
		{
			Vector2 temp = new Vector2(buttonPositionList.get(i).x + m_sprite.getX(),
	                   				   buttonPositionList.get(i).y + m_sprite.getY());
			buttonList.get(i).setPosition(temp);
		}
		for (int i = 0; i < buttonList.size(); i++)
			buttonList.get(i).show();
		
		
	    for (int i = 0; i < runningTextList.size(); i++)
		{
			Vector2 temp = new Vector2(runningTextPositionList.get(i).x + m_sprite.getX(),
									   runningTextPositionList.get(i).y + m_sprite.getY());
			runningTextList.get(i).setPosition(temp);
		}
	    for (int i = 0; i < runningTextList.size(); i++)
	    	runningTextList.get(i).show();
	    
			
	}
	public boolean isHiding()
	{
		if (m_sprite.getAlpha() == 0.0f)
			return true;
		else
			return false;
		
	}
	public void hideForm()
	{
		m_sprite.setAlpha(0.0f);
		for (int i = 0; i < buttonList.size(); i++)
			buttonList.get(i).hide();
		for (int i = 0; i < runningTextList.size(); i++)
		{
			runningTextList.get(i).clearText();
			runningTextList.get(i).hide();
		}
	}

	@Override
	public void onUpdate(float pSecondsElapsed) {
		Camera tempCamera = Roller.cameraManager.getCamera();
		if (m_sprite.getAlpha() != 0)
			setByCameraPosition(tempCamera.getCenterX(), tempCamera.getCenterY());
		else
			setByCameraPosition(tempCamera.getCenterX() + 1000, tempCamera.getCenterY() + 1000);
		
	    for (int i = 0; i < buttonList.size(); i++)
		{
			Vector2 temp = new Vector2(buttonPositionList.get(i).x + m_sprite.getX(),
	                   				   buttonPositionList.get(i).y + m_sprite.getY());
			buttonList.get(i).setPosition(temp);
		}
	    
	    for (int i = 0; i < runningTextList.size(); i++)
		{
			Vector2 temp = new Vector2(runningTextPositionList.get(i).x + m_sprite.getX(),
									   runningTextPositionList.get(i).y + m_sprite.getY());
			runningTextList.get(i).setPosition(temp);
			runningTextList.get(i).showNextChar(pSecondsElapsed);
		}
	    //if (runningTextList.size() > 0)
	   // 	runningTextList.get(0).showNextChar(pSecondsElapsed);
		
	}

	@Override
	public void reset() {
		// TODO Auto-generated method stub
		
	}
	
	public void setByCameraPosition(float cameraX, float cameraY) {
		m_sprite.setPosition(cameraX + m_position.x - Roller.CAMERA_WIDTH / 2.0f,
				 			 cameraY + m_position.y - Roller.CAMERA_HEIGHT / 2.0f);
	}

	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onSensorChanged(SensorEvent event) {
		if (m_sprite != null)
		{
	    	float[] accelerometer_values = event.values.clone();
	    	if (Roller.orientation == Configuration.ORIENTATION_PORTRAIT)
	    	{
		    	if (Math.abs(accelerometer_values[1]) >= Math.abs(accelerometer_values[0]))
		    	{
		    		if (accelerometer_values[1] <= -Roller.GSENSOR_SENSITIVITY && m_direction != Direction.LEFT)
		    		{
		    			m_direction = Direction.LEFT;
		    			m_sprite.setRotation(90);
		    		    for (int i = 0; i < buttonList.size(); i++)
		    				buttonList.get(i).rotate(90);
		    		    for (int i = 0; i < runningTextList.size(); i++)
		    		    	runningTextList.get(i).rotate(90);
		    			
		    		}
		    		else if (accelerometer_values[1] > Roller.GSENSOR_SENSITIVITY && m_direction != Direction.RIGHT)
		    		{
		    			m_direction = Direction.RIGHT;
		    			m_sprite.setRotation(-90);
		    			for (int i = 0; i < buttonList.size(); i++)
		    				buttonList.get(i).rotate(-90);
		    			for (int i = 0; i < runningTextList.size(); i++)
		    		    	runningTextList.get(i).rotate(-90);
		    		}
		    	}
		    	else
		    	{
		    		if (accelerometer_values[0] <= -Roller.GSENSOR_SENSITIVITY && m_direction != Direction.DOWN)
		    		{
		    			m_direction = Direction.DOWN;
		    			m_sprite.setRotation(180);
		    			for (int i = 0; i < buttonList.size(); i++)
		    				buttonList.get(i).rotate(180);
		    			for (int i = 0; i < runningTextList.size(); i++)
		    		    	runningTextList.get(i).rotate(180);
		    		}
		    		else if (accelerometer_values[0] > Roller.GSENSOR_SENSITIVITY && m_direction != Direction.UP)
		    		{
		    			m_direction = Direction.UP;
		    			m_sprite.setRotation(0);
		    			for (int i = 0; i < buttonList.size(); i++)
		    				buttonList.get(i).rotate(0);
		    			for (int i = 0; i < runningTextList.size(); i++)
		    		    	runningTextList.get(i).rotate(0);
		    		}
		    	}
	    	}
	    	else
	    	{
		    	if (Math.abs(accelerometer_values[1]) >= Math.abs(accelerometer_values[0]))
		    	{
		    		if (accelerometer_values[1] <= -Roller.GSENSOR_SENSITIVITY && m_direction != Direction.DOWN)
		    		{
		    			m_direction = Direction.DOWN;
		    			m_sprite.setRotation(180);
		    			for (int i = 0; i < buttonList.size(); i++)
		    				buttonList.get(i).rotate(180);
		    			for (int i = 0; i < runningTextList.size(); i++)
		    		    	runningTextList.get(i).rotate(180);
		    		}
		    		else if (accelerometer_values[1] > Roller.GSENSOR_SENSITIVITY && m_direction != Direction.UP)
		    		{
		    			m_direction = Direction.UP;
		    			m_sprite.setRotation(0);
		    			for (int i = 0; i < buttonList.size(); i++)
		    				buttonList.get(i).rotate(0);
		    			for (int i = 0; i < runningTextList.size(); i++)
		    		    	runningTextList.get(i).rotate(0);
		    		}
		    	}
		    	else
		    	{
		    		if (accelerometer_values[0] <= -Roller.GSENSOR_SENSITIVITY && m_direction != Direction.RIGHT)
		    		{
		    			m_direction = Direction.RIGHT;
		    			m_sprite.setRotation(-90);
		    			for (int i = 0; i < buttonList.size(); i++)
		    				buttonList.get(i).rotate(-90);
		    			for (int i = 0; i < runningTextList.size(); i++)
		    		    	runningTextList.get(i).rotate(-90);
		    		}
		    		else if (accelerometer_values[0] > Roller.GSENSOR_SENSITIVITY && m_direction != Direction.LEFT)
		    		{
		    			m_direction = Direction.LEFT;
		    			m_sprite.setRotation(90);
		    			for (int i = 0; i < buttonList.size(); i++)
		    				buttonList.get(i).rotate(90);
		    			for (int i = 0; i < runningTextList.size(); i++)
		    		    	runningTextList.get(i).rotate(90);
		    		}
		    	}
	    	}
		}
	}

	@Override
	public void rotate(float angle) {
		// TODO Auto-generated method stub
		
	}
	public void initializeDirection(Direction direction) {
		switch (direction)
		{
		case UP:
			m_direction = Direction.UP;
			m_sprite.setRotation(0);
			for (int i = 0; i < buttonList.size(); i++)
				buttonList.get(i).rotate(0);
			for (int i = 0; i < runningTextList.size(); i++)
		    	runningTextList.get(i).rotate(0);
			break;
		case DOWN:
			m_sprite.setRotation(180);
			for (int i = 0; i < buttonList.size(); i++)
				buttonList.get(i).rotate(180);
			for (int i = 0; i < runningTextList.size(); i++)
		    	runningTextList.get(i).rotate(180);
			break;
		case LEFT:
			m_direction = Direction.LEFT;
			m_sprite.setRotation(90);
			for (int i = 0; i < buttonList.size(); i++)
				buttonList.get(i).rotate(90);
			for (int i = 0; i < runningTextList.size(); i++)
		    	runningTextList.get(i).rotate(90);
			break;
		case RIGHT:
			m_direction = Direction.RIGHT;
			m_sprite.setRotation(-90);
			for (int i = 0; i < buttonList.size(); i++)
				buttonList.get(i).rotate(-90);
			for (int i = 0; i < runningTextList.size(); i++)
		    	runningTextList.get(i).rotate(-90);
			break;
		}
	}
	
	public void actionButtonCall()
	{
		if (runningTextList.size() == 0 || runningTextList.get(0).ActionClicked() )
		{
			
			this.hideForm();
			((Roller)m_game).unpause();
			Roller.actionButton.setState(ButtonState.CONTROLABLE);
		}

	}
	public void setRunningText(String[] texts)
	{
		if (runningTextList.size() > 0)
			runningTextList.get(0).setRunningText(texts);
	}
}
